package ext.tianma.changeManager.util;

import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.LoggerFactory;

import wt.doc.WTDocument;
import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.fc.ReferenceFactory;
import wt.fc.WTObject;
import wt.fc.collections.WTHashSet;
import wt.httpgw.URLFactory;
import wt.inf.container.WTContainerRef;
import wt.lifecycle.LifeCycleTemplate;
import wt.org.WTPrincipalReference;
import wt.part.WTPart;
import wt.query.QuerySpec;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.workflow.definer.WfProcessTemplate;
import wt.workflow.engine.ProcessData;
import wt.workflow.engine.WfEngineHelper;
import wt.workflow.engine.WfEngineServerHelper;
import wt.workflow.engine.WfProcess;
import ext.com.iba.IBAUtil;
import ext.com.workflow.WorkflowUtil;
import ext.tianma.bom.service.rfq.RFQService;
import ext.tianma.bom.util.GenericUtil;
import ext.tianma.changeManager.service.ChangeService;
import ext.tianma.model.RDPBOMModel;
import ext.tianma.model.RDPChange;
import ext.tianma.util.PropertiesUtil;
import ext.tianma.workflow.BomWorkFlowUtil;
import ext.tianma.workflow.SubmitBomReview;

/**
 * 类名: ProcessUtil </br>
 * 包名: ext.tianma.changeManager.util
 * 描述: 自启流程
 * @author xucr
 * 创建时间: 2020年12月11日
 * 发布版本: V1.0
 */
public class ProcessUtil {
	
	private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ProcessUtil.class);

	/**
	 * 创建流程
	 * @param processTemplate		工作流模板名称
	 * @param lifeCycleTemplate 	生命周期模板实例
	 * @param wtobject				发起流程的对象
	 * @param processName			流程名称
	 * @param owner					对象责任人
	 * @param wtcontainer			容器
	 * @return
	 * @author xucr
	 * @CreateDate 2020年12月11日
	 */
	public static WfProcess createProcess(String processTemplate, 
			LifeCycleTemplate lifeCycle ,WTObject wtobject, 
			String processName, WTPrincipalReference reference, WTContainerRef wtcontainer,
			Map<String, Object> maps) {
		WfProcess wfprocess = null;
		try {
			//获取流程模板
			WfProcessTemplate wfprocessTemplate = SubmitBomReview.getWfProcessTemplateByName(processTemplate);
			//获取生命周期
//			LifeCycleTemplate lifeCycle = LifeCycleHelper.service.getLifeCycleTemplate("生命周期模板", wt.inf.container.WTContainerHelper.getExchangeRef());
		
			wfprocess = WfEngineHelper.service.createProcess(wfprocessTemplate, lifeCycle, wtcontainer);
			WfEngineServerHelper.service.setPrimaryBusinessObject(wfprocess, wtobject);
			wfprocess.setName(processName);
			ProcessData processdata = wfprocess.getContext();
			wfprocess.setCreator(reference);
			
			//设置流程变量
			if(null != maps && maps.size() > 0) {
				for(String key : maps.keySet()) {
					processdata.setValue(key, maps.get(key));
				}
			}
			wfprocess = (WfProcess)PersistenceHelper.manager.save(wfprocess);	
			wfprocess.start(processdata, true, wtcontainer);
		} catch (WTException e) {
			e.printStackTrace();
			logger.error("createProcess >>>catch1 >>>>>: " + e.getLocalizedMessage(Locale.getDefault()));
		} catch (WTPropertyVetoException e) {
			e.printStackTrace();
			logger.error("createProcess >>>catch2 >>>>>: " + e.getLocalizedMessage(Locale.getDefault()));
		}
		return wfprocess;
	}
	
	/**
	 * 在流程中初始化物料变更信息页面
	 * @param self
	 * @param pbo
	 * @param key
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年12月16日
	 */
	public static String getChangeInfoUrl(ObjectReference self, Persistable pbo, int key) throws WTException {
		String str = "";
		String baseHref = new URLFactory().getBaseHREF();

		ReferenceFactory rf = new ReferenceFactory();
		WfProcess process = BomWorkFlowUtil.getProcess(self);
		String wid = rf.getReferenceString(process);

		if (pbo instanceof WTPart) {//APL材料审批流程：主对象是部件
			WTPart part = (WTPart) pbo;
			String oid = rf.getReferenceString(part);
			switch (key) {
				case 0:
					str = "<a href=\"Javascript:var processWindow = window.open('" + baseHref
							+ "netmarkets/jsp/ext/tianma/part/change/ChangeInfo.html?oid=" + oid + "&wid=" + wid
							+ " ', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
							+ "查看" + "</a>";
					break;
	
				default:
					break;
			}
		}
		return str;
	}
	
	/**
	 * 物料变更流程(RDP)走完成后，修改物料信息
	 * @param self
	 * @param pbo
	 * @author xucr
	 * @CreateDate 2020年12月16日
	 */
	public static void updatePartInfo(ObjectReference self, Persistable pbo) {
		WTPart part = (WTPart) pbo;
		WfProcess wf = (WfProcess) WorkflowUtil.getProcess(self);
		String rdpId = (String) wf.getContext().getValue("rdpId");
		String module = (String) wf.getContext().getValue("module");
		String changeData = "";
		RDPChange change = QueryUtil.findRDPChange(part, rdpId, module);
		try {
			if(null != change) {
				changeData = ChangeUtil.blob2str(change.getChangeInfo());
				if(StringUtils.isNotEmpty(changeData)) {
					JSONObject changeObject = new JSONObject(changeData);
					Iterator iter = changeObject.keys();
					part = (WTPart) GenericUtil.checkout(part);
					Hashtable<String, Object> table = new Hashtable<String, Object>();
					while(iter.hasNext()) {
						String key = (String) iter.next();
						String changeValue = ChangeUtil.getJSONString(changeObject, key);
						table.put(key, changeValue);
					}
					if(table.size() > 0) {
						IBAUtil.forceSetIBAValues(part, table);
					}
					GenericUtil.checkin(part);
				}
			}
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
		} catch (WTPropertyVetoException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 当流程结束时，设置RDPChange状况
	 * @param self
	 * @param pbo
	 * @author xucr
	 * @CreateDate 2020年12月18日
	 */
	public static void setState2RDPChange(ObjectReference self, Persistable pbo, String status) {
		/**
		 * 通过RDP发起的文档签审、图纸发布、物料编码进阶流程，允许废弃，因此状况多样性
		 * */
		try {
			WfProcess process = BomWorkFlowUtil.getProcess(self);
			String rdpId = (String) process.getContext().getValue("rdpId");
			String module = (String) process.getContext().getValue("module") ;
			//如果是物料进阶流程，变量中是含有：oldPart 
			Long id = 0L;
			String type = "";
			if(process.getContext().isVariable(ChangeService.OLDPART)) { //物料进阶
				WTPart oldPart = (WTPart) process.getContext().getValue(ChangeService.OLDPART);
				id = oldPart.getPersistInfo().getObjectIdentifier().getId();
				type = "料号进阶";
			} else if(process.getContext().isVariable(ChangeService.OLDDOC)){ //文档
				WTDocument oldDoc = (WTDocument) process.getContext().getValue(ChangeService.OLDDOC);
				id = oldDoc.getPersistInfo().getObjectIdentifier().getId();//当前流程对象
				type = "文档修订";
			}
			
			logger.info("info: 进阶类型:" + type);
			logger.error("error: 进阶类型:" + type);
			logger.debug("debug: 进阶类型:" + type);
			
			//校验变更管理中各大流程是否已经走完（工艺文件、图文档、物料修改、BOM变更）
			JSONObject params1 = new JSONObject();
			params1.put("module", module);
			params1.put("persistableId", id);
			
			QuerySpec qs1 = QueryUtil.queryRDPChange(rdpId, params1);
			QueryResult qr1 = PersistenceHelper.manager.find(qs1);
			
			WTHashSet set = new WTHashSet();
			while(qr1.hasMoreElements()) {
				RDPChange change = (RDPChange) qr1.nextElement();
				change.setStatus(status);
				set.add(change);
			}
			if(set.size() > 0) {
				PersistenceHelper.manager.save(set);	
			}
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
		} catch (WTPropertyVetoException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 当流程结束时，设置RDPBOMModel状况
	 * @param self
	 * @param pbo
	 * @author xucr
	 * @CreateDate 2020年12月18日
	 */
	public static void setState2RDPBOMModel(ObjectReference self) {
		/**
		 * 通过RDP发起的BOM变更，不会有取消，只能正常结束，因此状况为closed
		 * */
		try {
			WfProcess process = BomWorkFlowUtil.getProcess(self);
			String rdpId = (String) process.getContext().getValue("rdpId");
			
			QuerySpec qs2 = QueryUtil.queryRDPBOMModel(rdpId, null);
			QueryResult qr2 = PersistenceHelper.manager.find(qs2);
			
			WTHashSet set = new WTHashSet();
			while(qr2.hasMoreElements()) {
				RDPBOMModel model = (RDPBOMModel) qr2.nextElement();
				model.setStatus(ChangeService.CLOSED);
				set.add(model);
			}
			if(set.size() > 0) {
				PersistenceHelper.manager.save(set);	
			}
		} catch (WTException e) {
			e.printStackTrace();
		} catch (WTPropertyVetoException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 工作流模板中调用RDP接口，生成token
	 * @param self
	 * @author xucr
	 * @CreateDate 2020年12月18日
	 */
	public static void sendRDP(ObjectReference self, Persistable pbo) {
		try {
			WfProcess process = BomWorkFlowUtil.getProcess(self);
			String rdpId = (String) process.getContext().getValue("rdpId");
			
			//校验变更管理中各大流程是否已经走完（工艺文件、图文档、物料修改、BOM变更）
			JSONObject params1 = new JSONObject();
			params1.put("status", ChangeService.OPEN);
			
			QuerySpec qs1 = QueryUtil.queryRDPChange(rdpId, params1);
			QueryResult qr1 = PersistenceHelper.manager.find(qs1);
			
			QuerySpec qs2 = QueryUtil.queryRDPBOMModel(rdpId, params1);
			QueryResult qr2 = PersistenceHelper.manager.find(qs2);
			
			//判断当前RDPID对应的流程是否走完
			boolean isClosed = true;
			if(qr1.size() > 0 || qr2.size() > 0) {
				isClosed = false;
			}
			logger.info("info: isClosed:" + isClosed);
			logger.error("error: isClosed:" + isClosed);
			logger.debug("debug: isClosed:" + isClosed);
			//当对应流程走完后
			if(isClosed) {
				String configFilePath = "codebase" + File.separator + "ext" + File.separator + "tianma" + File.separator + "cfg"
						+ File.separator + "TianmaPro.properties";
				String token = PropertiesUtil.getRDPToken(configFilePath);
				
				logger.info("info: token:" + token);
				logger.error("error: token:" + token);
				logger.debug("debug: token:" + token);
				
				PropertiesUtil ut = new PropertiesUtil(configFilePath);
				String rdpUrl = ut.getValueByKey("erdp.url") + "/tmrdp/v1/change/apply/windchill" ;
				
				logger.info("info rdpUrl:" + rdpUrl);
				logger.error("error rdpUrl:" + rdpUrl);
				logger.debug("debug rdpUrl:" + rdpUrl);
				
				JSONObject params = new JSONObject();
				params.put("status", ChangeService.FAILED);
				QuerySpec qs = QueryUtil.queryRDPChange(rdpId, params);
				QueryResult qr = PersistenceHelper.manager.find(qs);
				String flowState = "04";//RDP定义的状态码
				if(qr.size() > 0) {//流程都结束，但有流程被废弃
					flowState = "06";
				}
				
				logger.info("info flowState:" + flowState);
				logger.error("error flowState" + flowState);
				logger.debug("debug flowState:" + flowState);
				
				//构造数据推送RDP
				JSONObject sendRdp = new JSONObject();
				sendRdp.put("flowState", flowState);
				sendRdp.put("rdpId", rdpId);
				
				logger.info("info sendRDP:" + sendRdp.toString());
				logger.error("error sendRDP:" + sendRdp.toString());
				logger.error("debug sendRDP:" + sendRdp.toString());
				sendRDP(sendRdp.toString(), rdpUrl, token);
			}
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 调用rdp接口，推送数据
	 * @param sendRdpInfo
	 * @param rdpUrl
	 * @param token
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @author xucr
	 * @CreateDate 2020年12月18日
	 */
	private static void sendRDP(String sendRdpInfo, String rdpUrl, String token) {
		try {
			String erdpUrl = rdpUrl;
			String key = "Authorization";
			
			String result = RFQService.sendJsonDataByPost(erdpUrl, sendRdpInfo, token, key);
			
			logger.info("info 推送RDP结果:" + result);
			logger.error("error 推送RDP结果:" + result);
			logger.debug("debug 推送RDP结果:" + result);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}	
}
